#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Network Agent - Implements registration, heartbeat and task processing
"""

print("=== 程序开始执行 ===")
import os
import time
import json
import logging
import threading
import requests
from typing import Dict, Any, Optional
from datetime import datetime, timedelta
from tools import generate_agent_id, load_env_file, execute_job_function, get_system_info
from api_server import AgentAPIServer, set_agent_instance

print("导入模块成功")

# 加载环境变量
load_env_file()
print("AGENT_SERVER_URL:", os.getenv('AGENT_SERVER_URL'))
print("AGENT_ID:", os.getenv('AGENT_ID'))

# 配置日志
log_level = os.getenv('LOG_LEVEL', 'INFO').upper()
log_level_map = {
    'DEBUG': logging.DEBUG,
    'INFO': logging.INFO,
    'WARNING': logging.WARNING,
    'ERROR': logging.ERROR,
    'CRITICAL': logging.CRITICAL
}
logging.basicConfig(
    level=log_level_map.get(log_level, logging.INFO),
    format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)


class NetworkAgent:
   
    def __init__(self):
        
        # Get base URL from environment variable, default for development
        self.base_url = os.getenv('AGENT_SERVER_URL', 'http://derucci-ci-cd.com')
        # 总是使用生成的包含主机信息和IP的ID
        self.agent_id = generate_agent_id()
        print("生成的Agent ID:", self.agent_id)
        
        # API endpoints
        self.register_url = "{}/outside/agents/register".format(self.base_url)
        self.heartbeat_url = "{}/outside/agents/heartbeat".format(self.base_url)
        self.joblist_url = "{}/outside/agents/jobList".format(self.base_url)
        self.jobupdate_url = "{}/outside/agents/jobUpdate".format(self.base_url)
        self.jobresult_url = "{}/outside/agents/jobResult".format(self.base_url)
        self.info_url = "{}/outside/agents/systemInfo".format(self.base_url)
        
        # Status management
        self.is_registered = False
        self.is_running = False
        self.heartbeat_interval = 10  # 10秒心跳间隔
        
        # Thread management
        self.heartbeat_thread = None
        self.job_thread = None
        self.info_thread = None
        
        # HTTP API服务器
        self.api_server = AgentAPIServer(self, port=int(os.getenv('API_PORT', 8888)))
        set_agent_instance(self)
        
        # Request session
        self.session = requests.Session()
        self.session.timeout = 30
    
    def register(self) -> bool:
        """Register to Server"""
        try:
            payload = {
                'agentId': self.agent_id,
                'timestamp': datetime.now().isoformat(),
                'status': 'online'
            }
            
            logger.info("正在注册Agent: {}".format(self.agent_id))
            logger.info("注册请求地址: {}".format(self.register_url))
            logger.info("注册请求数据: {}".format(payload))
            response = self.session.post(self.register_url, json=payload)
            
            if response.status_code == 200:
                self.is_registered = True
                logger.info("Agent注册成功")
                return True
            else:
                logger.error("注册失败: {} - {}".format(response.status_code, response.text))
                return False
                
        except Exception as e:
            logger.error("注册过程中发生错误: {}".format(e))
            return False
    
    def send_heartbeat(self):
        """发送心跳"""
        while self.is_running:
            try:
                payload = {
                    'agentId': self.agent_id,
                    'timestamp': datetime.now().isoformat(),
                    'status': 'alive'
                }
                
                logger.debug("心跳请求地址: {}".format(self.heartbeat_url))
                response = self.session.post(self.heartbeat_url, json=payload)
                logger.debug("心跳响应: status={}, text={}".format(response.status_code, response.text))
                
                if response.status_code == 200:
                    logger.debug("心跳发送成功")
                else:
                    logger.warning("心跳发送失败: {}".format(response.status_code))
                    
            except Exception as e:
                logger.error("发送心跳时发生错误: {}".format(e))
            
            time.sleep(self.heartbeat_interval)
    
    def send_system_info(self):
        """每小时准点发送系统信息"""
        while self.is_running:
            try:
                # 计算到下一个整点的等待时间
                now = datetime.now()
                next_hour = now.replace(minute=0, second=0, microsecond=0) + timedelta(hours=1)
                wait_seconds = (next_hour - now).total_seconds()
                
                # 等待到整点
                if wait_seconds > 0:
                    time.sleep(wait_seconds)
                
                if not self.is_running:
                    break
                
                # 获取系统信息
                system_info = get_system_info()
                if system_info:
                    payload = {
                        'agentId': self.agent_id,
                        'timestamp': datetime.now().isoformat(),
                        'systemInfo': system_info
                    }
                    
                    logger.info("发送系统信息到服务器")
                    logger.debug("系统信息数据: {}".format(system_info))
                    
                    response = self.session.post(self.info_url, json=payload)
                    
                    if response.status_code == 200:
                        logger.info("系统信息发送成功")
                    else:
                        logger.warning("系统信息发送失败: {}".format(response.status_code))
                else:
                    logger.warning("无法获取系统信息")
                    
            except Exception as e:
                logger.error("发送系统信息时发生错误: {}".format(e))
                # 如果出错，等待1小时后重试
                time.sleep(3600)

    def fetch_and_process_jobs(self):
        """获取并处理任务"""
        while self.is_running:
            try:
                # 请求任务列表 - 使用GET方式
                params = {
                    'agentId': self.agent_id,
                    'timestamp': datetime.now().isoformat()
                }
                
                logger.debug("任务请求地址: {}".format(self.joblist_url))
                logger.debug("任务请求参数: {}".format(params))
                response = self.session.get(self.joblist_url, params=params)
                
                if response.status_code == 200:
                    jobs_data = response.json()
                    jobs = jobs_data.get('data', [])
                    
                    if jobs:
                        logger.info("获取到 {} 个任务".format(len(jobs)))
                        
                        for job in jobs:
                            # 输出job的数据格式
                            logger.info("任务数据格式: {}".format(job))
                            # 处理任务
                            result = self.process_job(job)
                            
                            # 返回处理结果
                            self.submit_job_result(result)
                    else:
                        logger.debug("暂无任务")
                        
                else:
                    logger.warning("获取任务失败: {}".format(response.status_code))
                    
            except Exception as e:
                logger.error("获取任务时发生错误: {}".format(e))
            
            time.sleep(5)  # 5秒后再次请求任务
    
    def process_job(self, job: Dict[str, Any]) -> Dict[str, Any]:
        """处理具体的任务 - 根据fun_name动态调用对应方法"""
        job_id = job.get('id', 'unknown')
        fun_name = job.get('fun_name', 'unknown')
        
        logger.info("开始处理任务: {}, 方法: {}".format(job_id, fun_name))
        
        # 更新任务状态为进行中
        self.update_job_status(job_id, 'running')
        
        try:
            # 调用tools.py中对应的方法
            task_result = execute_job_function(job)
        
            # 返回处理结果
            result = {
                'jobId': job_id,
                'agentId': self.agent_id,
                'status': task_result.get('status', 'None'),
                'result': task_result,
                'timestamp': datetime.now().isoformat()
            }
            
            logger.debug("任务处理结果: {}".format(result))
            
            logger.info("任务 {} 处理完成，状态: {}".format(job_id, task_result.get('status')))
            return result
            
        except Exception as e:
            logger.error("处理任务 {} 时发生错误: {}".format(job_id, e))
            return {
                'jobId': job_id,
                'agentId': self.agent_id,
                'status': 'failed',
                'error': str(e),
                'timestamp': datetime.now().isoformat()
            }
    
    def update_job_status(self, job_id: str, status: str):
        """更新任务状态"""
        try:
            payload = {
                'jobId': job_id,
                'agentId': self.agent_id,
                'status': status,
                'timestamp': datetime.now().isoformat()
            }
            
            logger.info("更新任务状态: {} -> {}".format(job_id, status))
            response = self.session.post(self.jobupdate_url, json=payload)
            
            if response.status_code == 200:
                logger.info("任务状态更新成功: {}".format(job_id))
            else:
                logger.warning("任务状态更新失败: {} - {}".format(response.status_code, response.text))
                
        except Exception as e:
            logger.error("更新任务状态时发生错误: {}".format(e))
    
    def submit_job_result(self, result: Dict[str, Any]):
        """提交任务结果"""
        try:
            response = self.session.post(self.jobresult_url, json=result)
            
            if response.status_code == 200:
                logger.info(f"任务结果提交成功: {result['jobId']}")
            else:
                logger.error(f"任务结果提交失败: {response.status_code}")
                
        except Exception as e:
            logger.error(f"提交任务结果时发生错误: {e}")
    
    def start(self):
        """启动Agent"""
        print("启动网络Agent...")
        print("服务器地址: {}".format(self.base_url))
        print("Agent ID: {}".format(self.agent_id))
        logger.info("启动网络Agent...")
        logger.info("服务器地址: {}".format(self.base_url))
        logger.info("Agent ID: {}".format(self.agent_id))
        
        # 首先注册
        print("开始注册...")
        if not self.register():
            print("注册失败，Agent启动中止")
            logger.error("注册失败，Agent启动中止")
            return
        
        self.is_running = True
        
        # 启动心跳线程
        self.heartbeat_thread = threading.Thread(target=self.send_heartbeat, daemon=True)
        self.heartbeat_thread.start()
        logger.info("心跳线程已启动")
        
        # 启动任务处理线程
        self.job_thread = threading.Thread(target=self.fetch_and_process_jobs, daemon=True)
        self.job_thread.start()
        logger.info("任务处理线程已启动")
        
        # 启动系统信息上报线程
        self.info_thread = threading.Thread(target=self.send_system_info, daemon=True)
        self.info_thread.start()
        logger.info("系统信息上报线程已启动")
        
        # 启动HTTP API服务器
        self.api_server.start_server()
        
        logger.info("Agent启动完成，开始工作...")
        
        try:
            # 主线程保持运行
            while self.is_running:
                time.sleep(1)
        except KeyboardInterrupt:
            logger.info("收到停止信号，正在关闭Agent...")
            self.stop()
    
    def stop(self):
        """停止Agent"""
        logger.info("正在停止Agent...")
        self.is_running = False
        
        # 等待线程结束
        if self.heartbeat_thread and self.heartbeat_thread.is_alive():
            self.heartbeat_thread.join(timeout=5)
        
        if self.job_thread and self.job_thread.is_alive():
            self.job_thread.join(timeout=5)
        
        if self.info_thread and self.info_thread.is_alive():
            self.info_thread.join(timeout=5)
        
        logger.info("Agent已停止")
        

def main():
    """主函数"""
    agent = NetworkAgent()
    
    try:
        agent.start()
    except Exception as e:
        logger.error(f"Agent运行时发生错误: {e}")
    finally:
        agent.stop()


if __name__ == "__main__":
    main()